package crons

import (
	"context"
	"database/sql"
	"errors"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/shopspring/decimal"
	"hotgo/internal/consts"
	"hotgo/internal/library/cron"
	"hotgo/internal/model/entity"
	"hotgo/internal/model/input/sysin"
	"hotgo/internal/service"
	"time"
)

func init() {
	cron.Register(AuctionLogSettlement)
}

// AuctionLogSettlement 结算竞拍日志
var AuctionLogSettlement = &cAuctionLogSettlement{name: "auction_log_settlement"}

type cAuctionLogSettlement struct {
	name string
}

func (c *cAuctionLogSettlement) GetName() string {
	return c.name
}

// Execute 执行任务
func (c *cAuctionLogSettlement) Execute(ctx context.Context, parser *cron.Parser) (err error) {
	var (
		workingLog []entity.AuctionLog
	)
	//g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
	// 查询可用竞拍活动
	if err = service.SysAuctionLog().Model(ctx).
		Where("status", consts.AuctionLogWorking).
		Wheref("(end_time <= ? AND date = ?) OR date < ?", time.Now().Format(time.TimeOnly), time.Now().Format(time.DateOnly), time.Now().Format(time.DateOnly)).
		Scan(&workingLog); err != nil {
		parser.Logger.Warning(ctx, "cron AuctionLogSettlement Execute err: ", err)
		return err
	}
	for _, log := range workingLog {
		if log.NumberOfParticipants > 0 {
			if err = createOrder(ctx, log); err != nil {
				parser.Logger.Warning(ctx, "cron AuctionLogSettlement Execute err: ", err)
			}
		}
		if _, err = service.SysAuctionLog().Model(ctx).
			WherePri(log.Id).
			Data(g.Map{
				"status": consts.AuctionLogEnd,
			}).Update(); err != nil {
			parser.Logger.Warning(ctx, "cron AuctionLogSettlement Execute err: ", err)
		}
	}
	return err
	//})

	//return
}

func createOrder(ctx context.Context, log entity.AuctionLog) (err error) {
	var order entity.Order
	// 查询竞拍记录
	if err = service.SysUserOrder().Model(ctx).Where("auction_log_id", log.Id).Scan(&order); err != nil && !errors.Is(err, sql.ErrNoRows) {
		return err
	}
	if order.Id > 0 {
		return gerror.New("订单已存在")
	}

	if err = service.SysUserOrder().AuctionOrderCreate(ctx, &sysin.AuctionOrderPayInp{
		ProductID:    int64(log.ProductId),
		Amount:       decimal.NewFromInt(0),
		Point:        decimal.NewFromFloat(log.FinalPrice),
		UserID:       int64(log.LastUserId),
		AuctionLogID: log.Id,
	}); err != nil {
		return
	}
	return
}
